﻿using System.ComponentModel.DataAnnotations.Schema;
using System.Reflection;
using Core.Domain;
using Core.Domain.Contracts;
using FluentMigrator.Builders.Create;

namespace Core.Migrations.Extensions;
public static class MigrationExpressions
{
    public static string GetTableName(this Type type)
    {
        return CommonHelper.GetAttribute<TableAttribute>(type).Name;
    }

    public static string GetColumnName(this Type type, string propertyName)
    {
        PropertyInfo property = type.GetProperty(propertyName) ?? throw new Exception($"{type}迁移异常，{propertyName}字段未找到");

        var attribute = property.GetCustomAttribute<ColumnAttribute>();
        if (attribute != null)
        {
            return attribute.Name!;
        }

        return property.Name;
    }

    public static string ColumnNameFor<T>(string propertyName)
    {
        return typeof(T).GetColumnName(propertyName);
    }

    public static string TableNameFor<T>()
    {
        return typeof(T).GetTableName();
    }

    public static void CreateTableForTEntity<TEntity>(ICreateExpressionRoot createExpression)
    {
        createExpression
           .Table(TableNameFor<TEntity>())
           .WithColumn(typeof(TEntity).GetColumnName(nameof(IEntity<Guid>.Id)))
           .AsGuid().PrimaryKey().WithColumnDescription("主键")
           .WithColumn(nameof(BaseEntity.Sort)).AsInt32().Nullable().WithColumnDescription("排序")
           .WithColumn(nameof(BaseEntity.Description)).AsString(500).Nullable().WithColumnDescription("描述")
           .WithColumn(nameof(BaseEntity.Enabled)).AsBoolean().Nullable().WithColumnDescription("禁用/启用");
    }

    public static void CreateTableAuditableEntityFor<TEntity>(ICreateExpressionRoot createExpression, string schema) where TEntity : AuditableEntity
    {
        createExpression
           .Table(TableNameFor<TEntity>())
           .InSchema(schema)
           .WithColumn(typeof(TEntity).GetColumnName(nameof(IEntity<Guid>.Id)))
           .AsGuid().PrimaryKey().WithColumnDescription("主键")
           .WithColumn(nameof(AuditableEntity.Sort)).AsInt32().Nullable().WithColumnDescription("排序")
           .WithColumn(nameof(AuditableEntity.Description)).AsString(500).Nullable().WithColumnDescription("描述")
           .WithColumn(nameof(AuditableEntity.Enabled)).AsBoolean().Nullable().WithColumnDescription("禁用/启用")
           .WithColumn(nameof(AuditableEntity.Created)).AsDateTimeOffset().Nullable().WithDefaultValue(DateTime.Now).WithColumnDescription("创建时间")
           .WithColumn(nameof(AuditableEntity.CreatedBy)).AsGuid().Nullable().WithColumnDescription("创建者")
           .WithColumn(nameof(AuditableEntity.CreatedByName)).AsString(100).Nullable().WithColumnDescription("创建者账号")
           .WithColumn(nameof(AuditableEntity.LastModified)).AsDateTimeOffset().Nullable().WithColumnDescription("修改时间")
           .WithColumn(nameof(AuditableEntity.LastModifiedBy)).AsGuid().Nullable().WithColumnDescription("修改者")
           .WithColumn(nameof(AuditableEntity.LastModifiedByName)).AsString(100).Nullable().WithColumnDescription("修改者账号")
           .WithColumn(nameof(AuditableEntity.Deleted)).AsDateTimeOffset().Nullable().WithColumnDescription("删除时间")
           .WithColumn(nameof(AuditableEntity.DeletedBy)).AsGuid().Nullable().WithColumnDescription("删除者")
           .WithColumn(nameof(AuditableEntity.DeletedByName)).AsString(100).Nullable().WithColumnDescription("删除者账号");
    }
}
